import json
import logging
import os
import traceback
from datetime import datetime
from django.db import transaction
from django.forms import model_to_dict
from django.http import JsonResponse, HttpResponse
from rest_framework import status
from Model.models import District, Subdistrict, Community, Address
from Model.modelsView import SubDistrictInfo, CommunityInfo, AddressInfo
from mgtServer.settings import MEDIA_ROOT
from tools.Tools import check_text, getCurrentUser, createHandleLog, readFile, getFileBytes
from onu.models import OltInfo, BoardInfo
from tools.autoregister.autoregister import telnetip as HuaWeiClient
from tools.autoregister.zte_autoregister import telnetip as ZTEClient

logger_info = logging.getLogger('info')
res = dict()


# @transaction.atomic
def importHost(request):
    res.clear()
    try:
        if request.method == 'POST':
            body = json.loads(request.body)
            res_list = body.get('list')
            result = batchAddOlt(request, res_list)
            return JsonResponse(result, status=status.HTTP_200_OK)
    except Exception as e:
        print(e)
        logger_info.error(f'当前接口：{request.path} 异常，异常内容为:{traceback.format_exc()}')
        res['status'] = 400
        res['message'] = '请求错误!'
        return JsonResponse(res, status=status.HTTP_400_BAD_REQUEST)


def downloadHost(request):
    res.clear()
    try:
        if request.method == 'GET':
            out_stream = getFileBytes('host.xls')
            response = HttpResponse(content_type='application/vnd.ms-excel', charset="UTF-8")
            response.write(out_stream)
            return response
    except Exception as e:
        print(e)
        logger_info.error(f'当前接口：{request.path} 异常，异常内容为:{traceback.format_exc()}')
        res['status'] = 400
        res['message'] = '请求错误!'
        return JsonResponse(res, status=status.HTTP_400_BAD_REQUEST)


def isch(word):
    for ch in word:
        if '\u4e00' <= ch <= '\u9fff':
            return True
    return False


def batchAddOlt(request, hostList):
    global save_id, board_result
    try:
        for i in hostList:
            username_staff = "ceshi"
            time1 = datetime.now()
            olt_type = i['OLT类型']
            olt_name = i['OLT名称']
            olt_system_name = i['系统名称']
            olt_ip = i['IP']
            olt_port = i['端口']
            olt_account = i['账号']
            olt_passwd = i['密码']
            up_port = i['上联端口']
            line_template_gpon = i['线路模板GPON']
            business_template_gpon = i['业务模板GPON']
            line_template_epon = i['线路模板EPON']
            business_template_epon = i['业务模板EPON']
            business_outer = i['业务外层']
            business_intimal = i['业务内层']
            try:
                line_template_gpon = int(line_template_gpon)
                business_template_gpon = int(business_template_gpon)
                line_template_epon = int(line_template_epon)
                business_template_epon = int(business_template_epon)
                business_intimal = int(business_intimal)
                business_outer = int(business_outer)
                olt_port = int(olt_port)
            except Exception as e:
                print(e)
                result = {"status": 400, 'message': "线路模板、业务模板、业务外层、业务内层、设备端口、保存间隔必须填写数字"}
                return result

            result = isch(olt_account)
            if result:
                result = {"status": 400, 'message': "登录账号不允许使用中文"}
                return result
            result = isch(olt_passwd)
            if result:
                result = {"status": 400, 'message': "登录密码不允许使用中文"}
                return result
            if OltInfo.objects.filter(olt_name=olt_name).exists():
                result = {"status": 400, 'message': "设备名称已存在"}
                return result
            if OltInfo.objects.filter(olt_ip=olt_ip, olt_port=olt_port).exists():
                result = {"status": 400, 'message': "设备IP地址：%s 端口：%s 已存在" % (olt_ip, olt_port)}
                return result
            board_port = []
            board_dict = {}
            # 是否获取板卡信息
            # if 1:

            try:
                # 显式的开启一个事务
                if not OltInfo.objects.filter(olt_ip=olt_ip).exists():
                    with transaction.atomic():
                        save_id = transaction.savepoint()
                        data = OltInfo.objects.create()
                        data.olt_id = data.id
                        data.olt_ip = olt_ip
                        data.olt_name = olt_name
                        data.olt_system_name = olt_system_name
                        data.olt_mode = olt_type
                        data.olt_port = olt_port
                        data.olt_account = olt_account
                        data.olt_passwd = olt_passwd
                        data.up_port = up_port
                        data.up_down_remind = True
                        data.save_mode = 'autosave'
                        data.save_hours = 12
                        data.run_status = 0
                        data.save()
                        transaction.savepoint_commit(save_id)
                else:
                    result = {"status": 400, "message": "不能添加已有主机名称"}
                    return result
            except Exception as e:
                transaction.savepoint_rollback(save_id)
                result = {"status": 400, 'message': "提交失败 %s" % e}
                return result
            if olt_type == '华为':
                tl = HuaWeiClient(olt_ip, olt_port, olt_account, olt_passwd)
            elif olt_type == '中兴':
                tl = ZTEClient(olt_ip, olt_port, olt_account, olt_passwd)
            else:
                result = {"status": 400, 'msg': "暂不支持该设备类型"}
                return result
            state, result = tl.login_host(time_out=10, userrole="user")
            if state:
                config_result = tl.base_config(autosave=False, userrole="user")
                if config_result:
                    # 获取板卡命令
                    # display board 0
                    board_result, null = tl.board_info(scope="usable", userrole="user")
                    if board_result:
                        if olt_type == '华为':
                            print('发现板卡')
                            for i in board_result:
                                print(i)
                                # 获取某个板卡信息
                                # display board 0/i[0]
                                port_num_list = tl.board_one(board_num=i[0] if olt_type == '华为' else i[2], scope="port_num")
                                if port_num_list:
                                    board_dict["slotid"] = i[0]
                                    board_dict["port_num_list"] = port_num_list
                                    print('插入口')
                                    board_port.append(board_dict.copy())
                        else:
                            for i in board_result:
                                # 获取单个板卡信息
                                board_dict["slotid"] = i[2]
                                port_list = []
                                for j in range(1, int(i[5]) + 1):
                                    port_list.append(j)
                                board_dict["port_num_list"] = port_list
                                board_port.append(board_dict.copy())
                    else:
                        result = {"status": 400, "message": "登录%s 基本配置失败" % olt_name}
                        tl.logout_host()
                        return result
            else:
                result = {"status": 400, "message": "连接%s异常，失败原因：%s" % (olt_name, result)}
                return result
            print("board_port", board_port)
            # data = {"status": 200, 'result': "提交失败 %s"}
            # print() JsonResponse(data)
            # 创建事务保存点

            try:
                with transaction.atomic():
                    save_id = transaction.savepoint()
                    BoardInfo.objects.create(line_template_gpon=line_template_gpon if line_template_gpon else 0,
                                             business_template_gpon=business_template_gpon if business_template_gpon else 0,
                                             line_template_epon=line_template_epon if line_template_epon else 0,
                                             business_template_epon=business_template_epon if business_template_epon else 0,
                                             business_intimal=business_intimal if business_intimal else 0,
                                             business_outer=business_outer if business_outer else 0,
                                             gemport=0,
                                             default_data="Y",
                                             run_mode="full-automatic",
                                             # full-automatic or semi-automatic debugging
                                             filtration="false",
                                             olt_info_id=data.olt_id,
                                             created_time=time1)
                    # 已有板卡生成板卡数据
                    if board_port:
                        for board in board_port:
                            for i in board["port_num_list"]:
                                BoardInfo.objects.create(frameid=0,
                                                         slotid=board["slotid"],
                                                         board_port=i,
                                                         line_template_gpon=line_template_gpon if line_template_gpon else 0,
                                                         business_template_gpon=business_template_gpon if business_template_gpon else 0,
                                                         line_template_epon=line_template_epon if line_template_epon else 0,
                                                         business_template_epon=business_template_epon if business_template_epon else 0,
                                                         business_intimal=business_intimal if business_intimal else 0,
                                                         business_outer=business_outer if business_outer else 0,
                                                         gemport=0,
                                                         default_data=None,
                                                         run_mode="full-automatic",
                                                         # full-automatic or semi-automatic debugging
                                                         filtration="false",
                                                         olt_info_id=data.olt_id,
                                                         created_time=time1)

                    transaction.savepoint_commit(save_id)
            except Exception as e:
                transaction.savepoint_rollback(save_id)
                result = {"status": 400, 'message': "提交失败 %s" % e}
                return result
            tl.logout_host()
            # 提交成功，显式的提交一次事务
            createHandleLog('单个主机提交成功', str(getCurrentUser(request)), f'名称：{olt_name} IP：{olt_ip}')
        result = {'status': 200, 'message': '导入完成'}
        createHandleLog('所有主机提交成功', str(getCurrentUser(request)), f'全部完成')
        return result
    except:
        logger_info.error(f'当前接口：{request.path} 异常，异常内容为:{traceback.format_exc()}')
        result = {'status': 400, 'message': '导入失败'}
        return result
